package com.scs.application.modules.dept.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.consts.SerialKeys;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.flow.FlowContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UtilNum;
import com.scs.application.modules.base.entity.Matr;
import com.scs.application.modules.base.mapper.MatrMapper;
import com.scs.application.modules.base.util.CommonService;
import com.scs.application.modules.dept.entity.DeptReturn;
import com.scs.application.modules.dept.entity.DeptReturnItem;
import com.scs.application.modules.dept.mapper.DeptReturnItemMapper;
import com.scs.application.modules.dept.mapper.DeptReturnMapper;
import com.scs.application.modules.dept.service.DeptReturnItemService;
import com.scs.application.modules.dept.service.DeptReturnService;
import com.scs.application.modules.purchase.enums.PurchaseType;
import com.scs.application.modules.wm.entity.TertiaryStock;
import com.scs.application.modules.wm.entity.WorkOrder;
import com.scs.application.modules.wm.mapper.TertiaryStockMapper;
import com.scs.application.modules.wm.service.InOrderService;
import com.scs.application.modules.wm.service.TertiaryStockService;
import com.scs.application.modules.wm.service.WorkOrderService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 */
@Service
public class DeptReturnServiceImpl extends BaseServiceImpl<DeptReturnMapper, DeptReturn> implements DeptReturnService {
    @Autowired
    private InOrderService inOrderService;

    @Autowired
    private WorkOrderService workOrderService;

    @Autowired
    private DeptReturnItemMapper deptReturnItemMapper;

    @Autowired
    private DeptReturnItemService deptReturnItemService;

    @Resource
    private TertiaryStockMapper tertiaryStockMapper;

    @Resource
    private TertiaryStockService tertiaryStockService;

    @Resource
    private MatrMapper matrMapper;

    @Override
    public boolean saveOrUpdate(DeptReturn deptReturn) {
        if (StringUtils.isBlank(deptReturn.getBusKey())) {
            deptReturn.setBusKey(serialRuleAdapter.getSerialRuleService().generateCode(SerialKeys.DEPT_RETURN_KEY));
        }
        return super.saveOrUpdate(deptReturn);
    }

    @Override
    public boolean removeCascadeByIds(Collection<? extends Serializable> idList) {
        deptReturnItemMapper.delete(new QueryWrapper<DeptReturnItem>().in("dept_return_id", idList));
        return this.removeByIds(idList);
    }

    @Override
    protected void beforeHandleFlowChange(FlowContext flowContext, DeptReturn newEntity) {
        super.beforeHandleFlowChange(flowContext, newEntity);
        String buttonKey = flowContext.getButtonKey();

        DeptReturn transfer = flowContext.getBusEntity();


        // 提交审核，不允许空明细提交
        if ("submit".equalsIgnoreCase(buttonKey)) {
            Integer count = deptReturnItemMapper.selectCount(Wrappers.<DeptReturnItem>query().eq("dept_return_id", flowContext.getBusId()));
            if (count == null || count == 0) {
                throw new BusinessException("退库明细为空,请添加后提交");
            }

            DeptReturn deptReturnDb = this.getById(newEntity.getId());

            List<DeptReturnItem> returnItemList = deptReturnItemMapper
                    .selectList(Wrappers.<DeptReturnItem>query().eq("dept_return_id", flowContext.getBusId()));

            returnItemList.forEach(ob -> {
                CommonService.checkDeptReturn(ob.getSn(),ob.getSkuQty(),deptReturnDb.getDeptId(),ob, deptReturnDb);
            });

            //            强制修复金额
            returnItemList.forEach(ob -> {
                //单品数量*单品价格 是否等于 合计金额
                if(UtilNum.mul(ob.getSkuQty(),ob.getSkuPrice()) != ob.getAmount())  {
                    ob.setAmount(UtilNum.mul(ob.getSkuQty(),ob.getSkuPrice()));
                    //单品数量*单品价格 是否等于 合计金额
                    deptReturnItemMapper.updateById(ob);
                }
            });

            final double[] amountDtl = {0};
            returnItemList.forEach(item -> amountDtl[0] =UtilNum.sum(amountDtl[0],item.getAmount()));
            if (amountDtl[0] != deptReturnDb.getAmount()) {
                deptReturnDb.setAmount(amountDtl[0]);
                this.updateById(deptReturnDb);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void afterHandleFlowChange(FlowContext flowContext, DeptReturn newEntity) {
        DeptReturn deptReturn = flowContext.getBusEntity();
        String buttonKey = flowContext.getButtonKey();
        if(deptReturn.flowModified == null){
            deptReturn.setFlowModified(newEntity.flowModified)
                    .setFlowModifier(newEntity.flowModifier);
        }
        super.afterHandleFlowChange(flowContext, newEntity);

        // 设备科审核确认
        if ("finish".equalsIgnoreCase(buttonKey)) {
            List<String> ids = new ArrayList<>();
            ids.add(newEntity.getId());
            CommonService.updatebillFlow(ids, LocalDateTime.now(),true);
        }

        boolean endNode = flowContext.isEndNode();
        if (!endNode) {
            return;
        }
        // 如果是结束节点，创建入库单和库存表
        List<DeptReturnItem> workOrderItems = deptReturnItemService.list(Wrappers.<DeptReturnItem>query()
                .eq("dept_return_id", deptReturn.getId()));
        DeptReturn deptReturnDb = this.getById(newEntity.getId());
        workOrderItems.forEach(item->{
            CommonService.checkDeptReturn(item.getSn(),item.getSkuQty(),deptReturn.getDeptId(),item,deptReturnDb);
        });
        // 试剂退库处理
        handleReturnReagent(workOrderItems);

        List<WorkOrder> workOrderList = inOrderService.createWorkOrderByDeptReturn(deptReturn);

        if (workOrderList == null || workOrderList.size() == 0) {
            throw new BusinessException("转换出库单失败");
        }
//        workOrderList.forEach(item -> {
//            workOrderService.post(item.getId());
//        });
        workOrderService.postBatch(workOrderList.stream().map(WorkOrder::getId).collect(Collectors.toList()));

        CommonService.updateBusTableSnum("dept_return",deptReturn.getId());
    }

    /**
     * 试剂退库处理
     * @param workOrderItems 退库详情
     */
    private void handleReturnReagent(List<DeptReturnItem> workOrderItems) {
        List<String> matrIds = workOrderItems.stream().map(DeptReturnItem::getMatrId).collect(Collectors.toList());
        // 过滤耗材类型为试剂的退库明细
        List<Matr> matrs = matrMapper.selectList(Wrappers.<Matr>query().in("id", matrIds).eq("base_type", PurchaseType.REAGENT.getKey()));
        if (CollectionUtils.isEmpty(matrs)) { return; }
        List<String> snList = new ArrayList<>();
        for (DeptReturnItem item : workOrderItems) {
            for (Matr matr : matrs) {
                if (item.getMatrId().equals(matr.getId())) {
                    snList.add(item.getSn());
                    break;
                }
            }
        }
        // 查询试剂三级库
        List<TertiaryStock> tertiaryStockList = tertiaryStockService.list(Wrappers.<TertiaryStock>query().in("sn", snList));
        if (CollectionUtils.isEmpty(tertiaryStockList)) {
            throw new BusinessException("未找到试剂三级库库存，请确认消耗的试剂来源是否正确");
        } else {
            Date now = new Date();
            for (TertiaryStock tertiaryStock : tertiaryStockList) {
                if (tertiaryStock.getPackageQty() == 0) {
                    throw new BusinessException(String.format("%s已经被消耗，请重新扫描", tertiaryStock.getMatrName()));
                } else {
                    // 试剂三级库扣减库存
                    tertiaryStock.setPackageQty(0.0);
                    tertiaryStock.setSkuQty(0.0);
                    tertiaryStock.setAmount(0.0);
                    tertiaryStock.setMdate(now);
                }
            }
            tertiaryStockService.updateBatchById(tertiaryStockList);
        }
    }

    @Override
    public Map getDeptReturn(String code){

        DeptReturn deptReturn = baseMapper.selectOne(Wrappers.<DeptReturn>query()
                .eq("bus_key", code));
        if (deptReturn == null) {
            throw new BusinessException("该退货单未找到！");
        }
        List<DeptReturnItem> workOrderItems = deptReturnItemService.list(Wrappers.<DeptReturnItem>query()
                .eq("dept_return_id", deptReturn.getId()));
        Map result = new HashMap();
        result.put("return", deptReturn);
        result.put("returnItems", workOrderItems);
        return result;
    }
}
